package com.yl.chainStore.control.user

import com.alibaba.fastjson.JSONObject
import com.baomidou.mybatisplus.core.toolkit.IdWorker
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.yl.chainStore.common.enums.Status
import com.yl.chainStore.control.BaseCtrl
import com.yl.chainStore.pojo.vo.WebSelectVo
import com.yl.chainStore.pojo.vo.user.RegisteredUserResult
import com.yl.chainStore.pojo.vo.user.RegisteredUserSelectVo
import com.yl.chainStore.pojo.vo.user.UpdatePasswordVo
import com.yl.chainStore.pojo.vo.user.UserBindDeptResVo
import com.yl.chainStore.services.IWebCompanyUserService
import com.yl.common.ErrorCode
import com.yl.common.Flag
import com.yl.common.UserType
import com.yl.common.control.ResponseBody
import com.yl.common.control.returnError
import com.yl.common.control.returnSuccess
import com.yl.common.getContext
import com.yl.users.common.enum.UserPackageTypeEnum
import com.yl.users.common.annotations.PermsCode
import com.yl.users.entity.CompanyUser
import com.yl.users.pojo.vo.CompanyUserSelectVo
import com.yl.users.pojo.vo.UserBindRoleVo
import com.yl.users.services.ICompanyDeptService
import com.yl.users.services.ICompanyUserService
import com.yl.users.services.ISysCompanyService
import org.springframework.transaction.annotation.Transactional
import org.springframework.transaction.interceptor.TransactionAspectSupport
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("company/user/user")
open class CompanyUserController(
	private val iCompanyUserService: ICompanyUserService,
	private val iSysCompanyService: ISysCompanyService,
	private val iCompanyDeptService: ICompanyDeptService,
	private val iWebCompanyUserService: IWebCompanyUserService
) : BaseCtrl() {

	/**
	 * 用户分页
	 */
	@PostMapping("page")
	@PermsCode("company:user:user:page")
	@Transactional
	open fun page(@RequestBody body: CompanyUserSelectVo): ResponseBody {
		val page = Page<CompanyUser>(body.current, body.size)
		return returnSuccess(iSysCompanyService.getCompanyUserPage(page, body))
	}

	/**
	 * 明细
	 */
	@GetMapping("detail/{id}")
	@PermsCode("company:user:user:detail")
	@Transactional
	open fun detail(@PathVariable id: Long): ResponseBody {
		val user = iCompanyUserService.getUser(id)
			?: return returnError(ErrorCode.DATA_IS_NOT_FIND)
		user.password = null
		user.salt = null
		if (user.superUserId != null && user.superUserId != 0L) {
			val user1 = iCompanyUserService.getUser(user.superUserId!!)
			if (user1 != null) {
				user1.password = null
				user1.salt = null
				user.superior = user1
			}
		}
		return returnSuccess(user)
	}


	/**
	 * 保存
	 */
	@PostMapping("save")
	@PermsCode("company:user:user:save")
	@Transactional(rollbackFor = [Exception::class])
	open fun save(@RequestBody user: CompanyUser): ResponseBody {
		user.userCode = IdWorker.get32UUID()
		user.flag = Flag.NEW_ADD
		user.userType = UserType.Company
		user.companyId = getContext().companyId
		if (user.id == 0L) {
			val addUser = iSysCompanyService.addUser(user)
			if (addUser.code != ErrorCode.SUCCESS.code) {
				return addUser
			}
		} else {
			val updateUser = iCompanyUserService.updateById(user)
			if (updateUser.code != ErrorCode.SUCCESS.code) {
				return updateUser
			}
		}
		iCompanyUserService.removeCacheUser(getContext().companyId, user.id)
		return returnSuccess()
	}

	/**
	 * 删除
	 */
	@PostMapping("del/{id}")
	@PermsCode("company:user:user:del")
	@Transactional(rollbackFor = [Exception::class])
	open fun del(@PathVariable id: Long): ResponseBody {
		val user = iCompanyUserService.getUser(id) ?: return returnError(ErrorCode.DATA_IS_NOT_FIND)
		if (user.companyId != getContext().companyId) {
			return returnError(ErrorCode.DATA_DELETE_FAILED, "没有权限删除")
		}
		if (user.id == getContext().userId) {
			return returnError(ErrorCode.DATA_DELETE_FAILED, "不能删除自己")
		}
		if ("admin" == user.userCode) {
			return returnError(ErrorCode.DATA_DELETE_FAILED, "不能删除管理员")
		}
		user.enabled = 0
		iCompanyUserService.delUser(user.id)
		iCompanyUserService.removeCacheUser(getContext().companyId, user.id)
		return returnSuccess()
	}

	/**
	 * 修改密码
	 */
	@PostMapping("updatePassword")
	@PermsCode("company:user:user:password")
	@Transactional(rollbackFor = [Exception::class])
	open fun updatePassword(@RequestBody vo: UpdatePasswordVo):ResponseBody{
		if(vo.userId == null){
			return returnError(ErrorCode.OPERATION_DATA_ERROR,"请选择用户")
		}
		val updatePassword = iCompanyUserService.updatePassword(
			vo.userId,
			vo.oldPassword,
			vo.newPassword
		)
		if(updatePassword.bodyIsError()){
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
			return updatePassword
		}

		return returnSuccess()
	}

	/**
	 * 用户 分院-角色  列表
	 */
	@PostMapping("getUserBindSubCompanyList/{id}")
	@Transactional
	open fun getUserBindSubCompanyList(@PathVariable id: Long): ResponseBody {
		val userSubCompanyList = iCompanyUserService.getUserSubCompanyList(id)
		val resList = mutableListOf<UserBindDeptResVo>()
		for (ud in userSubCompanyList) {
			resList.add(
				UserBindDeptResVo(
					ud.companyDeptId,
					iCompanyUserService.getUserSubCompanyRole(id, ud.companyDeptId)
				)
			)
		}
		return returnSuccess(resList)
	}

	/**
	 * 用户直接绑定分院
	 */
	@PostMapping("bindUserToSubCompany")
	@Transactional
	open fun bindUserToSubCompany(@RequestBody body: JSONObject): ResponseBody {
		val userId = body.getLong("userId") ?: return returnError(ErrorCode.PARAM_EMPTY, "请选择用户")
		val subCompanyId = body.getLong("subCompanyId") ?: return returnError(ErrorCode.PARAM_EMPTY, "请选择部门")
		return iCompanyDeptService.bindUserToSubCompany(userId, subCompanyId)
	}

	/**
	 * 用户绑定部门（再绑定分院）
	 */
	@PostMapping("bindUserToDept")
	@PermsCode("company:user:dept:bindDept")
	@Transactional
	open fun bindUserToDept(@RequestBody body: JSONObject): ResponseBody {
		val userId = body.getLong("userId") ?: return returnError(ErrorCode.PARAM_EMPTY, "请选择用户")
		val deptId = body.getLong("deptId") ?: return returnError(ErrorCode.PARAM_EMPTY, "请选择部门")
		return iCompanyDeptService.bindUserToDept(deptId, userId)
	}

	/**
	 * 绑定角色
	 */
	@PostMapping("bindUserRole")
	@PermsCode("company:user:dept:bindRole")
	@Transactional
	open fun bindUserRole(@RequestBody vo: UserBindRoleVo): ResponseBody {
		if (vo.subCompanyId != getContext().subCompanyId) {
			return returnError(ErrorCode.OPERATION_DATA_ERROR, "请到对应分院为该用户授权")
		}
		return iCompanyUserService.bindRoles(vo.userId, vo.subCompanyId, vo.roleIds)
	}

	/**
	 * 解绑
	 */
	@PostMapping("unBindUserToSubCompany")
	@PermsCode("company:user:dept:unBind")
	@Transactional
	open fun unBindUserToSubCompany(@RequestBody body: JSONObject): ResponseBody {
		val userId = body.getLong("userId") ?: return returnError(ErrorCode.PARAM_EMPTY, "请选择用户")
		val subCompanyId = body.getLong("subCompanyId") ?: return returnError(ErrorCode.PARAM_EMPTY, "请选择部门")
		return iCompanyDeptService.unBindUserToSubCompany(userId, subCompanyId)
	}

	/**
	 * 上级用户用
	 */
	@PostMapping("getUserByName")
	@Transactional
	open fun getUserByName(@RequestBody body: CompanyUserSelectVo): ResponseBody {
		return returnSuccess(iSysCompanyService.getCompanyUserList(body))
	}

	/**
	 * 用户类型
	 */
	@GetMapping("getAllUserType")
	open fun getAllUserType(): ResponseBody {
		val list = mutableListOf<Map<String, Any>>()
		list.add(UserPackageTypeEnum.COMPANY_USER_TYPE_DOCTOR.getMap())
		list.add(UserPackageTypeEnum.COMPANY_USER_TYPE_NURSE.getMap())
		list.add(UserPackageTypeEnum.COMPANY_USER_TYPE_CONSULT.getMap())
		list.add(UserPackageTypeEnum.COMPANY_USER_TYPE_ONLINE_MARKETING.getMap())
		list.add(UserPackageTypeEnum.COMPANY_USER_TYPE_FRONT_DESK.getMap())
		return returnSuccess(list)
	}

	/**
	 * 查询咨询师（可带其他参数，post方法）
	 */
	@PostMapping("getConsultUserByStatus")
	@Transactional
	open fun getConsultUserByStatus(@RequestBody vo: RegisteredUserSelectVo): ResponseBody {
		val page = iCompanyDeptService.getSubCompanyUserPage(
			Page(1, 10),
			CompanyUserSelectVo(
				realName = vo.name,
				userWorkType = UserPackageTypeEnum.COMPANY_USER_TYPE_CONSULT
			), getContext().subCompanyId
		)
		val list = mutableListOf<RegisteredUserResult>()
		for (u in page.records) {
			// TODO: 2021/9/16 查看客户状态
			val userStatusResult =
				iWebCompanyUserService.getUserStatusResult(u, UserPackageTypeEnum.COMPANY_USER_TYPE_CONSULT)
			if (vo.status == null || vo.status == Status.ALL || vo.status == userStatusResult.status) {
				list.add(userStatusResult)
			}
		}
		return returnSuccess(list)
	}

	/**
	 * 查询护士（可带其他参数，post方法）
	 */
	@PostMapping("getNurseUserByStatus")
	@Transactional
	open fun getNurseUserByStatus(@RequestBody vo: RegisteredUserSelectVo): ResponseBody {
		val page = iCompanyDeptService.getSubCompanyUserPage(
			Page(1, 10),
			CompanyUserSelectVo(
				realName = vo.name,
				userWorkType = UserPackageTypeEnum.COMPANY_USER_TYPE_NURSE
			), getContext().subCompanyId
		)
		val list = mutableListOf<RegisteredUserResult>()
		for (u in page.records) {
			val userStatusResult =
				iWebCompanyUserService.getUserStatusResult(u, UserPackageTypeEnum.COMPANY_USER_TYPE_NURSE)
			if (vo.status == null || vo.status == Status.ALL || vo.status == userStatusResult.status) {
				list.add(userStatusResult)
			}
		}
		return returnSuccess(list)
	}

	/**
	 * 查询医生（可带其他参数，post方法）
	 */
	@PostMapping("getDoctorUserByStatus")
	@Transactional
	open fun getDoctorUserByStatus(@RequestBody vo: RegisteredUserSelectVo): ResponseBody {
		val page = iCompanyDeptService.getSubCompanyUserPage(
			Page(1, 1000), CompanyUserSelectVo(
				realName = vo.name,
				userWorkType = UserPackageTypeEnum.COMPANY_USER_TYPE_DOCTOR
			), getContext().subCompanyId
		)
		val list = mutableListOf<RegisteredUserResult>()
		for (u in page.records) {

			val userStatusResult =
				iWebCompanyUserService.getUserStatusResult(u, UserPackageTypeEnum.COMPANY_USER_TYPE_DOCTOR)
			if (vo.status == null || vo.status == Status.ALL || vo.status == userStatusResult.status) {
				list.add(userStatusResult)
			}

		}
		return returnSuccess(list)
	}

	/**
	 * 查询所有用户 下拉 选项
	 */
	@GetMapping("getUserList")
	@Transactional
	open fun getUserList(value: String?): ResponseBody {
		val userPage = iCompanyDeptService.getSubCompanyUserPage(
			Page(1, 10),
			CompanyUserSelectVo(realName = value),
			getContext().subCompanyId,
		)
		val list = mutableListOf<WebSelectVo>()
		for (user in userPage.records) {
			list.add(
				WebSelectVo(
					id = user.id,
					name = user.realName
				)
			)
		}
		return returnSuccess(list)
	}

	/**
	 * 查询医生 下拉 选项
	 */
	@GetMapping("getDoctorList")
	@Transactional
	open fun getDoctorList(value: String?): ResponseBody {
		val userPage = iCompanyDeptService.getSubCompanyUserPage(
			Page(1, 10),
			CompanyUserSelectVo(realName = value, userWorkType = UserPackageTypeEnum.COMPANY_USER_TYPE_DOCTOR),
			getContext().subCompanyId,
		)
		val list = mutableListOf<WebSelectVo>()
		for (user in userPage.records) {
			list.add(
				WebSelectVo(
					id = user.id,
					name = user.realName
				)
			)
		}
		return returnSuccess(list)
	}

	/**
	 * 查询医生 下拉 选项
	 */
	@GetMapping("getDoctorListAll")
	@Transactional
	open fun getDoctorListAll(value: String?): ResponseBody {
		val list = iCompanyDeptService.getSubCompanyUserList(
			CompanyUserSelectVo(realName = value, userWorkType = UserPackageTypeEnum.COMPANY_USER_TYPE_DOCTOR),
			getContext().subCompanyId,
		)
		val resList = mutableListOf<WebSelectVo>()
		for (user in list) {
			resList.add(
				WebSelectVo(
					id = user.id,
					name = user.realName
				)
			)
		}
		return returnSuccess(resList)
	}

	/**
	 * 查询护士 下拉 选项
	 */
	@GetMapping("getNurseList")
	@Transactional
	open fun getNurseList(value: String?): ResponseBody {
		val userPage = iCompanyDeptService.getSubCompanyUserPage(
			Page(1, 10),
			CompanyUserSelectVo(realName = value, userWorkType = UserPackageTypeEnum.COMPANY_USER_TYPE_NURSE),
			getContext().subCompanyId,
		)
		val list = mutableListOf<WebSelectVo>()
		for (user in userPage.records) {
			list.add(
				WebSelectVo(
					id = user.id,
					name = user.realName
				)
			)
		}
		return returnSuccess(list)
	}

	/**
	 * 查询护士 下拉 选项
	 */
	@GetMapping("getNurseListAll")
	@Transactional
	open fun getNurseListAll(value: String?): ResponseBody {
		val list = iCompanyDeptService.getSubCompanyUserList(
			CompanyUserSelectVo(realName = value, userWorkType = UserPackageTypeEnum.COMPANY_USER_TYPE_NURSE),
			getContext().subCompanyId,
		)
		val resList = mutableListOf<WebSelectVo>()
		for (user in list) {
			resList.add(
				WebSelectVo(
					id = user.id,
					name = user.realName
				)
			)
		}
		return returnSuccess(resList)
	}

	/**
	 * 查询咨询师 下拉 选项
	 */
	@GetMapping("getConsultList")
	@Transactional
	open fun getConsultList(value: String?): ResponseBody {
		val userPage = iCompanyDeptService.getSubCompanyUserPage(
			Page(1, 10),
			CompanyUserSelectVo(realName = value, userWorkType = UserPackageTypeEnum.COMPANY_USER_TYPE_CONSULT),
			getContext().subCompanyId,
		)
		val list = mutableListOf<WebSelectVo>()
		for (user in userPage.records) {
			list.add(
				WebSelectVo(
					id = user.id,
					name = user.realName
				)
			)
		}
		return returnSuccess(list)
	}

	/**
	 * 查询咨询师 下拉 选项
	 */
	@GetMapping("getNetConsultList")
	@Transactional
	open fun getNetConsultList(value: String?): ResponseBody {
		val userPage = iCompanyDeptService.getSubCompanyUserPage(
			Page(1, 10),
			CompanyUserSelectVo(realName = value, userWorkType = UserPackageTypeEnum.COMPANY_USER_TYPE_ONLINE_MARKETING),
			getContext().subCompanyId,
		)
		val list = mutableListOf<WebSelectVo>()
		for (user in userPage.records) {
			list.add(
				WebSelectVo(
					id = user.id,
					name = user.realName
				)
			)
		}
		return returnSuccess(list)
	}

	/**
	 * 查询咨询师 下拉 选项
	 */
	@GetMapping("getConsultListAll")
	@Transactional
	open fun getConsultListAll(value: String?): ResponseBody {
		val list = iCompanyDeptService.getSubCompanyUserList(
			CompanyUserSelectVo(realName = value, userWorkType = UserPackageTypeEnum.COMPANY_USER_TYPE_CONSULT),
			getContext().subCompanyId,
		)
		val resList = mutableListOf<WebSelectVo>()
		for (user in list) {
			resList.add(
				WebSelectVo(
					id = user.id,
					name = user.realName
				)
			)
		}
		return returnSuccess(resList)
	}

	/**
	 * 获取所有下级用户
	 */
	@GetMapping("getAllSubUser")
	@Transactional
	open fun getAllSubUser(value: String?): ResponseBody {
		val subUserList = iCompanyUserService.getSubUserList(
			getContext().userId, getContext().companyId,
			CompanyUserSelectVo(realName = value)
		)
		val resList = mutableListOf<Map<String, Any>>()
		for (u in subUserList) {
			val map = mutableMapOf<String, Any>()
			map["id"] = u.id
			map["name"] = u.realName
			resList.add(map)
		}
		return returnSuccess(resList)
	}

	/**
	 * 获取所有下级用户，包含自己
	 */
	@GetMapping("getAllSubUserAndSelf")
	@Transactional
	open fun getAllSubUserAndSelf(value: String?): ResponseBody {
		val subUserList = iCompanyUserService.getSubUserList(
			getContext().userId,
			getContext().companyId,
			CompanyUserSelectVo(realName = value)
		)
		val resList = mutableListOf<Map<String, Any>>()
		val user = iCompanyUserService.getUser(getContext().userId)
		if (user != null) {
			val userMap = mutableMapOf<String, Any>()
			userMap["id"] = user.id
			userMap["name"] = user.realName
			resList.add(userMap)
		}
		for (u in subUserList) {
			val map = mutableMapOf<String, Any>()
			map["id"] = u.id
			map["name"] = u.realName
			resList.add(map)
		}
		return returnSuccess(resList)
	}

}
